home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-09-30 | 13.4 KB | 685 lines | [TEXT/CWIE] |
- // COPYRIGHT 1995 A.D. Software, All rights reserved
-
- // PowerPlant Integration layer of OOFILE database
- #include "oofppx.hpp" // private interface, includes public
- #include "oof4.hpp" // extra field definitions
- #include "oofview.hpp"
-
- #include "stdlib.h"
- #ifdef _Windows
- #include <strstrea.h>
- #else
- #include <strstream.h>
- #endif
- #include "fstream.h"
-
-
-
-
- // include PowerPlant definitions
- #include <LEditField.h>
- #include <LListBox.h>
- #include <LTextEdit.h>
- #include <UMemoryMgr.h>
- #include <PP_Messages.h>
-
-
- // static variables
- dbDocHelper* dbDocHelper::sCurrentDoc = 0;
-
- // -------------------------------------------------------
- // d b D o c H e l p e r
- // -------------------------------------------------------
- dbDocHelper::dbDocHelper() :
- mAddFactory(0),
- mEditFactory(0),
- mBrowseFactory(0),
- mInterestedInRecordChanges(0)
- {};
-
-
- dbDocHelper::~dbDocHelper()
- {
- delete mAddFactory;
- delete mEditFactory;
- delete mBrowseFactory;
-
- }
-
-
- // the following pair of methods hint at a need to have some more
- // general dependency mechanism, probably as a mixin.
- // it WILL happen, once we've used this approach for a couple of apps
- // but will be transparent to clients of these classes anyway
- // as these dependencies are only within the framework
-
- void dbDocHelper::recordHasBeenChanged(dbWindowHelper* changedBy)
- {
- if (mInterestedInRecordChanges) {
- mInterestedInRecordChanges->recordHasBeenChanged(changedBy);
- }
- }
-
-
- void dbDocHelper::interestedInRecordChanges(dbWindowHelper* interestedParty)
- {
- mInterestedInRecordChanges = interestedParty;
- }
-
-
- // slightly sloppy duplicated code for now, this area is likely to change
- // so not worth investing time simplifying
- void dbDocHelper::AdoptAddDialogFactory(dbWindowFactory* factory)
- {
- #ifdef OOF_Debug
- if (mAddFactory)
- dbConnect::raise("dbDocHelper::adoptAddDialogFactory replacing current factory");
- #endif
- delete mAddFactory;
- mAddFactory = factory;
- }
-
-
- void dbDocHelper::AdoptEditDialogFactory(dbWindowFactory* factory)
- {
- #ifdef OOF_Debug
- if (mEditFactory)
- dbConnect::raise("dbDocHelper::adoptEditDialogFactory replacing current factory");
- #endif
- delete mEditFactory;
- mEditFactory = factory;
- }
-
-
-
- void dbDocHelper::AdoptBrowseWindowFactory(dbWindowFactory* factory)
- {
- #ifdef OOF_Debug
- if (mBrowseFactory)
- dbConnect::raise("dbDocHelper::adoptBrowseWindowFactory replacing current factory");
- #endif
- delete mBrowseFactory;
- mBrowseFactory = factory;
- mMainTable = factory->mainTable();
- }
-
-
- bool dbDocHelper::OOFILEhandlesMessage(const Int32 inMessage, void *ioParam)
- {
- switch (inMessage) {
- case 'dNew':
- NewRecord();
- return true;
-
- default:
- return false;
- }
- return false;
- }
-
-
- LWindow* dbDocHelper::MakeBrowser()
- {
- if (mBrowseFactory) {
- sCurrentDoc = this;
- return mBrowseFactory->makeWindow();
- }
- else
- return NULL;
- }
-
-
- LWindow* dbDocHelper::NewRecord()
- {
- if (mAddFactory) {
- sCurrentDoc = this;
- mMainTable->newRecord();
- return mAddFactory->makeWindow(false);
- }
- else
- return NULL;
- }
-
-
- LWindow* dbDocHelper::MakeEditor()
- {
- if (mEditFactory) {
- sCurrentDoc = this;
- return mEditFactory->makeWindow(true);
- }
- else
- return NULL;
- }
-
- // -------------------------------------------------------
- // d b W i n d o w H e l p e r
- // -------------------------------------------------------
-
- dbWindowHelper::dbWindowHelper()
- {
- LinkToDoc();
- }
-
-
- void dbWindowHelper::LinkToDoc()
- {
- mBossDoc = dbDocHelper::sCurrentDoc;
- }
-
-
- // -------------------------------------------------------
- // d b B r o w s e H e l p e r
- // -------------------------------------------------------
-
- dbBrowseHelper::dbBrowseHelper() :
- mBrowsingView(0),
- mBrowserDisplay(0)
- {
- mBossDoc->interestedInRecordChanges(this);
- }
-
-
- dbBrowseHelper::~dbBrowseHelper()
- {
- delete mBrowsingView;
- delete mBrowserDisplay;
- }
-
-
- void dbBrowseHelper::recordHasBeenChanged(dbWindowHelper* changedBy)
- {
- LoadBrowseData();
- }
-
-
- bool dbBrowseHelper::OOFILEhandlesMessage(
- const Int32 inMessage,
- void *ioParam)
- {
- switch (inMessage) {
- case cmd_dbNew:
- mBossDoc->NewRecord();
- // scope for us to react afterwards
- return true;
-
- case cmd_dbDoubleClick:
- case cmd_dbEdit:
- if (mBrowserDisplay)
- mBrowsingView->source()->gotoRelativeRecord(mBrowserDisplay->selectedRow());
- mBossDoc->MakeEditor();
- // scope for us to react afterwards
- return true;
-
- case cmd_dbDel:
- DelRecord();
- return true;
-
- default:
- return false;
- }
- return false;
- }
-
-
- void dbBrowseHelper::DelRecord()
- {
- SysBeep(30); // not implemented in demo
- }
-
-
- void dbBrowseHelper::AdoptView(dbView* theView)
- {
- if (mBrowsingView)
- if (mBrowserDisplay)
- mBrowserDisplay->changeViewTo(theView);
- delete mBrowsingView;
- mBrowsingView = theView;
- }
-
-
- void dbBrowseHelper::BrowseViewWithListBox(LListBox* theLB)
- {
- #ifdef OOF_Debug
- if (mBrowserDisplay)
- dbConnect::raise("dbBrowseHelper::BrowseViewWithListBox replacing current browser display");
- #endif
- delete mBrowserDisplay;
- mBrowserDisplay = new dbListBoxDisplay(theLB, mBrowsingView);
- }
-
-
- void dbBrowseHelper::LoadBrowseData()
- {
- if (mBrowserDisplay)
- mBrowserDisplay->loadData();
- }
-
-
- // -------------------------------------------------------
- // d b E d i t H e l p e r
- // -------------------------------------------------------
-
- dbEditHelper::dbEditHelper() :
- mNew(false),
- mChangingPages(false),
- mAutoSaveOnMoving(true),
- mMainTable(0)
- {
- }
-
-
- dbEditHelper::~dbEditHelper()
- {
- mLinks.deleteAll();
- delete mMainTable;
- }
-
-
- void dbEditHelper::LinkField(dbChar* fld, LEditField* ctl)
- {
- mLinks.append(new dbCharLink2EditField(fld, ctl));
- }
-
-
- void dbEditHelper::LinkField(dbChar* fld, LTextEdit* ctl)
- {
- mLinks.append(new dbCharLink2TextEdit(fld, ctl));
- }
-
-
- void dbEditHelper::LinkField(dbText* fld, LTextEdit* ctl)
- {
- mLinks.append(new dbTextLink2TextEdit(fld, ctl));
- }
-
-
- void dbEditHelper::LinkField(dbLong* fld, LEditField* ctl)
- {
- mLinks.append(new dbLongLink2EditField(fld, ctl));
- }
-
-
- void dbEditHelper::LinkField(dbShort* fld, LEditField* ctl)
- {
- mLinks.append(new dbShortLink2EditField(fld, ctl));
- }
-
-
- void dbEditHelper::LinkField(dbDate* fld, LEditField* ctl)
- {
- mLinks.append(new dbDateLink2EditField(fld, ctl));
- }
-
-
- void dbEditHelper::GoFirstRecord()
- {
- assert(mMainTable);
- if (mMainTable->atFirst())
- SysBeep(30);
- else
- {
- if(LeaveRecord()) {
- mMainTable->first();
- LoadData();
- }
- }
- }
-
-
- void dbEditHelper::GoNextRecord()
- {
- assert(mMainTable);
- if (mMainTable->atLast())
- SysBeep(30);
- else
- {
- if(LeaveRecord()) {
- mMainTable->next();
- LoadData();
- }
- }
- }
-
-
- void dbEditHelper::GoPrevRecord()
- {
- assert(mMainTable);
- if (mMainTable->atFirst())
- SysBeep(30);
- else
- {
- if(LeaveRecord()) {
- mMainTable->prev();
- LoadData();
- }
- }
- }
-
-
- void dbEditHelper::GoLastRecord()
- {
- assert(mMainTable);
- if (mMainTable->atLast())
- SysBeep(30);
- else
- {
- if(LeaveRecord()) {
- mMainTable->last();
- LoadData();
- }
- }
- }
-
-
- bool dbEditHelper::LeaveRecord()
- {
- if(CanLeaveRecord()) {
- if (mAutoSaveOnMoving)
- SaveRecord();
- return true;
- }
- else
- return false; // user-override says NO
- }
-
-
- void dbEditHelper::LoadData()
- {
- assert(mMainTable); // should be setup by now!
- EnteringAboutToLoad(); // user hook
- CopyFieldsToLinks();
- EnteringAfterLoad(); // user hook
- }
-
-
- void dbEditHelper::SaveRecord()
- {
- assert(mMainTable); // should be setup by now!
- LeavingAboutToSave(); // user hook
- CopyLinksToFields();
- mMainTable->saveRecord();
- LeavingAfterSave(); // user hook
- mBossDoc->recordHasBeenChanged(this); // will be more intelligent later about if record is REALLY changed
- }
-
-
- void dbEditHelper::warnUser(ostream& os)
- {
- #ifdef _Windows
- strstream oss;
- oss << os.rdbuf() << ends;
- char* s = oss.str();
- ::MessageBox(0, s, "Warning", MB_ICONEXCLAMATION);
- oss.rdbuf()->freeze(0); // leave buffer for stream to delete
- #else
- cout << os.rdbuf();
- #endif
- }
-
-
-
- void dbEditHelper::CopyLinksToFields()
- {
- int numLinks = mLinks.count();
- for (int i=0; i<numLinks; i++) {
- dbFieldLink* fl = (dbFieldLink*) (mLinks[i]); // safe downcast
- fl->copyLinkToField();
- mLinks.next();
- }
- }
-
-
- void dbEditHelper::CopyFieldsToLinks()
- {
- int numLinks = mLinks.count();
- for (int i=0; i<numLinks; i++) {
- dbFieldLink* fl = (dbFieldLink*) (mLinks[i]); // safe downcast
- fl->copyFieldToLink();
- mLinks.next();
- }
- }
-
-
- bool dbEditHelper::OOFILEhandlesMessage(
- const Int32 inMessage,
- void *ioParam)
- {
- switch (inMessage) {
- case msg_OK:
- if(CanLeaveRecord()) {
- SaveRecord();
- LCommander::GetDefaultCommander()->ProcessCommand(cmd_Close, ioParam);
- }
- return true;
-
- case msg_Cancel:
- LCommander::GetDefaultCommander()->ProcessCommand(cmd_Close, ioParam);
- return true;
-
- case cmd_dbFirst:
- GoFirstRecord();
- return true;
-
- case cmd_dbPrev:
- GoPrevRecord();
- return true;
-
- case cmd_dbNext:
- GoNextRecord();
- return true;
-
- case cmd_dbLast:
- GoLastRecord();
- return true;
-
- default:
- return false;
- }
- return false;
- }
-
-
-
- // -------------------------------------------------------
- // d b C h a r L i n k 2 E d i t F i e l d
- // -------------------------------------------------------
- void dbCharLink2EditField::copyFieldToLink()
- {
- Str255 str;
- mField->asStr255(str);
- mLinkTo->SetDescriptor(str);
- }
-
-
- void dbCharLink2EditField::copyLinkToField()
- {
- Str255 str;
- mLinkTo->GetDescriptor(str);
- mField->setStr255(str);
- }
-
-
-
- // -------------------------------------------------------
- // d b C h a r L i n k 2 T e x t E d i t
- // -------------------------------------------------------
- void dbCharLink2TextEdit::copyFieldToLink()
- {
- const char* c = *mField;
- Ptr p = const_cast<Ptr>(c);
- mLinkTo->SetTextPtr(p, mField->fieldDataLen());
- }
-
-
- void dbCharLink2TextEdit::copyLinkToField()
- {
- Handle h = mLinkTo->GetTextHandle();
- StHandleLocker playSafe(h);
- mField->setChars((char*) *h, GetHandleSize(h));
- }
-
-
- // -------------------------------------------------------
- // d b T e x t L i n k 2 T e x t E d i t
- // -------------------------------------------------------
- void dbTextLink2TextEdit::copyFieldToLink()
- {
- const char* c = *mField;
- Ptr p = const_cast<Ptr>(c);
- mLinkTo->SetTextPtr(p, mField->fieldDataLen());
- }
-
-
- void dbTextLink2TextEdit::copyLinkToField()
- {
- Handle h = mLinkTo->GetTextHandle();
- StHandleLocker playSafe(h);
- mField->setChars((char*) *h, GetHandleSize(h));
- }
-
-
-
- // -------------------------------------------------------
- // d b L o n g L i n k 2 E d i t F i e l d
- // -------------------------------------------------------
- void dbLongLink2EditField::copyFieldToLink()
- {
- mLinkTo->SetValue(*mField);
- }
-
-
- void dbLongLink2EditField::copyLinkToField()
- {
- *mField = mLinkTo->GetValue();
- }
-
-
-
- // -------------------------------------------------------
- // d b S h o r t L i n k 2 E d i t F i e l d
- // -------------------------------------------------------
- void dbShortLink2EditField::copyFieldToLink()
- {
- mLinkTo->SetValue(*mField);
- }
-
-
- void dbShortLink2EditField::copyLinkToField()
- {
- *mField = mLinkTo->GetValue();
- }
-
-
-
- // -------------------------------------------------------
- // d b D a t e L i n k 2 E d i t F i e l d
- // -------------------------------------------------------
- void dbDateLink2EditField::copyFieldToLink()
- {
- Str255 str;
- mField->asStr255(str);
- mLinkTo->SetDescriptor(str);
- }
-
-
- void dbDateLink2EditField::copyLinkToField()
- {
- Str255 str;
- mLinkTo->GetDescriptor(str);
- mField->setStr255(str);
- }
-
-
-
- // -------------------------------------------------------
- // d b L i s t B o x D i s p l a y
- // -------------------------------------------------------
- dbListBoxDisplay::dbListBoxDisplay(LListBox* theLB, dbView* theView) :
- mDisplay(theLB),
- mView(theView),
- mLoadedData(false)
- {
- theLB->SetDoubleClickMessage(cmd_dbDoubleClick);
- if (mView && theLB)
- SetColWidths();
-
- }
-
-
- void dbListBoxDisplay::loadData()
- // VERY, VERY coarse first attempt just to get a demo working
- {
- mDisplay->Hide();
- mLoadedData = true;
- DeleteAllData();
- ListHandle lh = mDisplay->GetMacListH();
- ::LAddColumn(mView->count(), 0, lh);
- int numRows = mView->source()->count();
- ::LAddRow(numRows, 0, lh);
-
- mView->source()->start();
- for (int i=0; i<numRows; i++) {
- LoadRow(i, false);
- mView->source()->next();
- }
- mDisplay->SetValue(0);
- mDisplay->Show();
- }
-
-
- void dbListBoxDisplay::LoadRow(const int row, bool insertTheRow)
- // again, some very inefficient code to get the demo working
- {
- ListHandle lh = mDisplay->GetMacListH();
- if (insertTheRow)
- ::LAddRow(1, row, lh);
- mView->start();
- Cell theCell;
- theCell.v = row;
- for (int col = 0; mView->more(); col++) {
- dbField *theField = (dbField *) (mView->item(col)); // safe downcast
- char* str = theField->copyAsChars(); // good test of allocator, in this loop!
- theCell.h = col;
- ::LSetCell(str, strlen(str), theCell, lh);
- delete str;
- mView->next();
- }
- }
-
-
- void dbListBoxDisplay::DeleteAllData()
- {
- ListHandle lh = mDisplay->GetMacListH();
- ::LDelColumn(0, 0, lh); // all cols in one go
- ::LDelRow(0, 0, lh); // all rows in one go
- }
-
-
- void dbListBoxDisplay::changeViewTo(dbView* theView)
- {
- mView = theView;
- SetColWidths();
- if (mLoadedData) // don't load yet if hadn't loaded other view
- loadData();
- }
-
-
- const long dbListBoxDisplay::selectedRow() const
- {
- return mDisplay->GetValue();
- }
-
-
- void dbListBoxDisplay::SetColWidths()
- {
- // logic copied from LListBox::ResizeFrameBy
- // which unfortunately we can't just call as it has a test to see if the cells are
- // already at the default width
- assert(mDisplay);
- assert(mView);
- ListHandle lh = mDisplay->GetMacListH();
- Rect displayRect = (**lh).rView;
- Point cellSize = (**lh).cellSize;
- cellSize.h = (displayRect.right - displayRect.left) / mView->count();
- ::LCellSize(cellSize, lh);
- }